<script lang="ts" setup>
import {
  ElButton,
  ElInput,
  Sort,
  ElDatePicker,
  ElDialog,
  ElForm,
  ElInputNumber,
  ElFormItem,
  ElCheckbox,
  ElNotification,
  type FormInstance,
  type DateModelType
} from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { Table } from '@/components/Table'
import { getReservationPrepayListApi } from '@/api/reservation-prepay'
import { createReservationRefundsApi } from '@/api/reservation-refund'
import { useTable } from '@/hooks/web/useTable'
import { reactive, ref, unref } from 'vue'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
import { TableColumn } from '@/types/table'
import { Search, SearchItem } from '@/components/Search'
import { ReservationPrepay } from '@/api/reservation-prepay/types'
import { ReservationRefund } from '@/api/reservation-refund/types'
import { formatDate, formatNumber } from '@/utils'
import { useValidator } from '@/hooks/web/useValidator'

defineOptions({
  name: 'ReservationPrepay'
})

const { push } = useRouter()
const { required } = useValidator()

const refundRules = reactive({
  reason: [required('请填写退款原因')],
  reference: [required('请认真填写备注，以便于查询审核')],
  refund_amount: [required('请输入退款金额')]
})

interface Conditions {
  openid: string
  dates: [DateModelType, DateModelType]
  room: string
  confirm_number: string
}

const reservationRefund = reactive<ReservationRefund>(new ReservationRefund())
const refundVisible = ref(false)
const refundFormRef = ref<FormInstance>()
const loading = ref(false)

const conditions = reactive<Conditions>({
  openid: '',
  dates: [dayjs().add(-30, 'days').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')],
  room: '',
  confirm_number: ''
})

const WxPrepayPaidStatus = {
  Waiting: '待支付',
  Terminated: '终止支付',
  Success: '支付成功'
}

const defaultSort = ref<Sort>({
  prop: 'created_at',
  order: 'descending'
})

const formatSearchParams = async (data: Conditions) => {
  return {
    openid: data.openid,
    start: data.dates[0],
    end: data.dates[1],
    room: data.room,
    confirm_number: data.confirm_number
  }
}

const { register, tableObject, methods } = useTable<ReservationPrepay>({
  getListApi: getReservationPrepayListApi,
  formatSearchParams,
  defaultSort: defaultSort.value
})

const { setSearchParams, onSortChanged } = methods

setSearchParams(conditions)

const tableColumns = reactive<TableColumn[]>([
  {
    field: 'confirm_number',
    label: '确认号',
    width: '120px',
    showOverflowTooltip: true
  },
  {
    field: 'wx_transaction_id',
    label: '微信单号',
    width: '280px'
  },
  {
    field: 'out_trade_no',
    label: '商户单号',
    width: '280px'
  },
  {
    field: 'amount',
    label: '金额',
    width: '100px',
    align: 'right',
    headerAlign: 'right',
    formatter: (row) => {
      return formatNumber(row.amount)
    }
  },
  {
    field: 'paid_status',
    label: '状态',
    width: '90px',
    formatter: (row) => {
      return WxPrepayPaidStatus[row.paid_status]
    }
  },
  {
    field: 'is_pms_posted',
    label: 'PMS入账',
    width: '90px',
    align: 'center',
    headerAlign: 'center',
    formatter: (row) => {
      return row.is_pms_posted ? 'Y' : 'N'
    }
  },
  {
    field: 'refund_amount',
    label: '退款金额',
    width: '100px',
    align: 'right',
    headerAlign: 'right',
    formatter: (row) => {
      return formatNumber(row.refund_amount)
    }
  },
  {
    field: 'paid_time',
    label: '付款时间',
    width: '200px',
    formatter: (row) => {
      return formatDate(row.paid_time, 'YYYY-MM-DD HH:mm')
    }
  },
  {
    field: 'openid',
    label: '小程序id',
    width: '260px'
  },
  {
    field: 'action',
    width: '120px',
    label: '操作',
    headerAlign: 'center',
    align: 'center'
  }
])

const DownloadAction = () => {
  push('/geography/region-add')
}

const selectedReservationPrepay = ref<ReservationPrepay>()
const RefundAction = (row: ReservationPrepay) => {
  unref(refundFormRef)?.resetFields()
  selectedReservationPrepay.value = row
  refundVisible.value = true
}

const onRefundConfirm = async () => {
  loading.value = true
  reservationRefund.reservation_prepay_id = selectedReservationPrepay.value?.id
  const { data } = await createReservationRefundsApi(reservationRefund).finally(
    () => (loading.value = false)
  )
  ElNotification.success(
    `已发起退款申请，微信支付退款单号为: ${data.refund_id}, 退款方式: ${data.user_received_account}`
  )
  refundVisible.value = false
  setSearchParams(conditions)
}
</script>

<template>
  <Search :model="conditions" @reset="setSearchParams" @search="setSearchParams">
    <SearchItem label="日期" prop="nickname">
      <ElDatePicker
        v-model="conditions.dates"
        :clearable="false"
        type="daterange"
        value-format="YYYY-MM-DD"
      />
    </SearchItem>
    <SearchItem label="房号" prop="room">
      <ElInput v-model="conditions.room" clearable maxlength="50" />
    </SearchItem>
    <SearchItem label="确认号" prop="confirm_nnumber">
      <ElInput v-model="conditions.confirm_number" clearable maxlength="50" />
    </SearchItem>
    <SearchItem label="小程序id" prop="openid">
      <ElInput v-model="conditions.openid" clearable maxlength="50" />
    </SearchItem>
  </Search>

  <div class="mt-10px bg-white p-20px">
    <div class="mb-10px flex flex-row justify-between">
      <div>列表</div>
      <div class="flex flex-row items-center">
        <ElButton :icon="Plus" type="primary" @click="DownloadAction">下载</ElButton>
        <Icon class="mr-8px ml-8px cursor-pointer" icon="ep:refresh-right" />
      </div>
    </div>

    <Table
      v-model:currentPage="tableObject.currentPage"
      v-model:pageSize="tableObject.pageSize"
      :columns="tableColumns"
      :data="tableObject.tableList"
      :default-sort="defaultSort"
      :loading="tableObject.loading"
      :pagination="{
        total: tableObject.total
      }"
      :selection="false"
      @register="register"
      @sort-change="onSortChanged"
    >
      <template #action="{ row }">
        <ElButton
          v-hasPermi="'miniprogram:deposit:refund'"
          link
          size="small"
          type="primary"
          @click="RefundAction(row)"
        >
          退款
        </ElButton>
      </template>
    </Table>
  </div>

  <ElDialog
    v-model="refundVisible"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    draggable
    title="退款申请"
    width="500px"
  >
    <ElForm ref="refundFormRef" :model="reservationRefund" :rules="refundRules" label-width="100">
      <ElFormItem label="退款原因" prop="reason">
        <ElInput
          v-model="reservationRefund.reason"
          :rows="2"
          maxlength="80"
          placeholder="退款原因，会下发通知给微信用户"
          type="textarea"
        />
      </ElFormItem>

      <ElFormItem label="备注" prop="reference">
        <ElInput
          v-model="reservationRefund.reference"
          :rows="2"
          maxlength="200"
          placeholder="请信息填写填空原因，便于财务审核"
          type="textarea"
        />
      </ElFormItem>

      <ElFormItem label="退款金额" prop="refund_amount">
        <ElInputNumber
          v-model="reservationRefund.refund_amount"
          :controls="false"
          :max="selectedReservationPrepay?.amount"
          :min="0"
          :precision="2"
        />
      </ElFormItem>

      <ElFormItem label="" prop="post_to_pms">
        <ElCheckbox v-model="reservationRefund.post_to_pms" label="自动转入Opera" />
      </ElFormItem>
    </ElForm>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="refundVisible = false">取消</el-button>
        <el-button :loading="loading" type="primary" @click="onRefundConfirm">确认</el-button>
      </span>
    </template>
  </ElDialog>
</template>
